package javango.contrib.hibernate;

import java.lang.annotation.Annotation;
import java.util.Iterator;

import javax.persistence.Column;

import javango.forms.Form;
import javango.forms.fields.CharField;
import javango.forms.fields.Field;

import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
import org.hibernate.validator.Length;

public class HibernateFormHelper {

	public static boolean isValid(Form form, Class<?> objectClass) {
		// TODO re-work this logic,  it can leed to NPE at the start of the for loop below
		if (form.getErrors() == null && !form.isValid()) return false;
		
		ClassValidator v = new ClassValidator(objectClass);
		
		for (String key : form.getCleanedData().keySet()) {
			Object value = form.getCleanedData().get(key);
			InvalidValue[] invalids = v.getPotentialInvalidValues(key, value);
			for (int i=0; i<invalids.length; i++) {
				form.getErrors().put(invalids[i].getPropertyName(), invalids[i].getMessage());
			}
		}
		return form.getErrors().isEmpty();
	}
	
	public static boolean isValid(Form form) {
		if (form.getErrors() == null && !form.isValid()) return false;
		
		ClassValidator validator = new ClassValidator(form.getClass());
		Iterator<Field> i = form.getFields().values().iterator();
		while (i.hasNext()) {
			Field f  = i.next();
			InvalidValue[] invalids = validator.getPotentialInvalidValues(f.getName(), form.getCleanedData().get(f.getName()));
			for (int x=0; x<invalids.length; x++) {
				form.getErrors().put(invalids[x].getPropertyName(), invalids[x].getMessage());
			}
		}
		
		return form.getErrors().isEmpty();
	}
	
	/**
	 * Processes all known hibernate annotations for known field types..
	 */
	public static void processHibernateAnnotation(Annotation annotation, Field field) {
		if (field instanceof CharField) {
			if (annotation instanceof Column) {
				if (((CharField)field).getMaxLength() == null) {
					((CharField)field).setMaxLength(((Column)annotation).length());
				}
			} else if (annotation instanceof Length) {
				if (((CharField)field).getMaxLength() == null) {
					((CharField)field).setMaxLength(((Length)annotation).max());
				}
			}
			
			// TODO Add additional...
		}
	}
}
